//
//  SocketEngineSpec.h
//  Socket.IO-Client
//
//  Created by alanwang.dev on 16/8/8.
//  Copyright © 2016年 com.alanwang.dev. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "SocketEngineClient.h"
#import "WebSocket.h"
#import "SocketTypes.h"
#import "SocketEnginePacketType.h"
#import "SocketTypes.h"
#import "Either.h"

@protocol SocketEngineSpecProtocol <NSObject>

@property (nonatomic, assign) BOOL closed;
@property (nonatomic, assign) BOOL connected;
@property (nonatomic, assign) NSDictionary *connectParams;
@property (nonatomic, assign) BOOL doubleEncodeUTF8;
@property (nonatomic, assign) NSArray<NSHTTPCookie *> *cookies;
@property (nonatomic, assign) NSDictionary *extraHeaders;
@property (nonatomic, assign) BOOL fastUpgrade;
@property (nonatomic, assign) BOOL forcePolling;
@property (nonatomic, assign) BOOL forceWebsockets;
@property (nonatomic, strong) dispatch_queue_t parseQueue;
@property (nonatomic, assign, readonly) BOOL polling;
@property (nonatomic, assign, readonly) BOOL probing;
@property (nonatomic, strong) dispatch_queue_t emitQueue;
@property (nonatomic, assign, readonly) dispatch_queue_t handleQueue;
@property (nonatomic, copy) NSString *sid;
@property (nonatomic, assign, readonly) NSString *socketPath;
@property (nonatomic, assign, readonly) NSURL *urlPolling;
@property (nonatomic, assign, readonly) NSURL *urlWebSocket;
@property (nonatomic, assign, readonly) BOOL websocket;
@property (nonatomic, readonly) WebSocket *ws;

- (instancetype)initWithClient:(id<SocketEngineClient> *)client url:(NSURL *)url options:(NSDictionary *)options;

- (void)connect;
- (void)didError:(NSString *)error;
- (void)disconnect:(NSString *)reason;
- (void)doFastUpgrade;
- (void)flushWaitingForPostToWebSocket;
- (void)parseEngineData:(NSData *)data;
- (void)parseEngineMessage:(NSString *)message fromPolling:(BOOL)fromPolling;
- (void)write:(NSString *)msg type:(SocketEnginePacketType)type Data:(NSArray <NSData *> *)data;

@end

// extension
@interface SocketEngineSpec : NSObject <SocketEngineSpecProtocol>

@property (nonatomic, assign) BOOL closed;
@property (nonatomic, assign) BOOL connected;
@property (nonatomic, assign) NSDictionary *connectParams;
@property (nonatomic, assign) BOOL doubleEncodeUTF8;
@property (nonatomic, assign) NSArray<NSHTTPCookie *> *cookies;
@property (nonatomic, assign) NSDictionary *extraHeaders;
@property (nonatomic, assign) BOOL fastUpgrade;
@property (nonatomic, assign) BOOL forcePolling;
@property (nonatomic, assign) BOOL forceWebsockets;
@property (nonatomic, strong) dispatch_queue_t parseQueue;
@property (nonatomic, assign) BOOL polling;
@property (nonatomic, assign) BOOL probing;
@property (nonatomic, strong) dispatch_queue_t emitQueue;
@property (nonatomic, strong) dispatch_queue_t handleQueue;
@property (nonatomic, copy) NSString *sid;
@property (nonatomic, assign) NSString *socketPath;
@property (nonatomic, strong) NSURL *urlPolling;
@property (nonatomic, strong) NSURL *urlWebSocket;
@property (nonatomic, assign) BOOL websocket;
@property (nonatomic, strong) WebSocket *ws;


@property (nonatomic, weak) id<SocketEngineClient> client;

#pragma mark - extension
@property (nonatomic, strong) NSURL *urlPollingWithSid;
@property (nonatomic, strong) NSURL *urlWebSocketWithSid;

/**
 *  @brief
 *
 *  @param data
 *
 *  @return <NSData, String>
 */
- (Either *)createBinaryDataForSend:(NSData *)data;

- (NSString *)doubleEncodeUTF8:(NSString *)string;

- (NSString *)fixDoubleUTF8:(NSString *)string;

/// Send an engine message (4)
- (void)send:(NSString *)msg datas:(NSArray<NSData *> *)datas;

@end
